package com.android.camera.animation;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.TimeInterpolator;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.widget.FrameLayout;

public class AnimationSlideInUnderneath extends Animation {

    private int mDirection;
    private int mPadding;

    public AnimationSlideInUnderneath(View view) {
        mView = view;
        mDirection = DIRECTION_LEFT;
        mInterpolator = new AccelerateDecelerateInterpolator();
        mDuration = DURATION_LONG;
        mListener = null;
    }

    @Override
    public void animate() {
        final ViewGroup parentView = (ViewGroup) mView.getParent();
        final FrameLayout slideInFrame = new FrameLayout(mView.getContext());
        final int positionView = parentView.indexOfChild(mView);
        slideInFrame.setLayoutParams(mView.getLayoutParams());
        slideInFrame.setClipChildren(true);
        parentView.removeView(mView);
        slideInFrame.addView(mView);
        parentView.addView(slideInFrame, positionView);

        ObjectAnimator slideInAnim = null;
        float viewWidth = mView.getWidth(), viewHeight = mView.getHeight();
        switch (mDirection) {
            case DIRECTION_LEFT:
                mView.setTranslationX(-viewWidth + mPadding);
                slideInAnim = ObjectAnimator.ofFloat(mView, View.TRANSLATION_X,
                        slideInFrame.getX());
                break;
            case DIRECTION_RIGHT:
                mView.setTranslationX(viewWidth - mPadding);
                slideInAnim = ObjectAnimator.ofFloat(mView, View.TRANSLATION_X,
                        slideInFrame.getX());
                break;
            case DIRECTION_UP:
                mView.setTranslationY(-viewHeight + mPadding);
                slideInAnim = ObjectAnimator.ofFloat(mView, View.TRANSLATION_Y,
                        slideInFrame.getY());
                break;
            case DIRECTION_DOWN:
                mView.setTranslationY(viewHeight - mPadding);
                slideInAnim = ObjectAnimator.ofFloat(mView, View.TRANSLATION_Y,
                        slideInFrame.getY());
                break;
            default:
                break;
        }
        slideInAnim.setInterpolator(mInterpolator);
        slideInAnim.setDuration(mDuration);
        slideInAnim.addListener(new AnimatorListenerAdapter() {

            @Override
            public void onAnimationStart(Animator animation) {
                mView.setVisibility(View.VISIBLE);
                if (getListener() != null) {
                    getListener().onAnimationStart(
                            AnimationSlideInUnderneath.this);
                }
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                slideInFrame.removeAllViews();
                mView.setLayoutParams(slideInFrame.getLayoutParams());
                parentView.addView(mView, positionView);
                if (getListener() != null) {
                    getListener().onAnimationEnd(
                            AnimationSlideInUnderneath.this);
                }
            }
        });
        slideInAnim.setStartDelay(mDelay);
        slideInAnim.start();
    }

    public int getDirection() {
        return mDirection;
    }

    public AnimationSlideInUnderneath setDirection(int direction) {
        mDirection = direction;
        return this;
    }

    public TimeInterpolator getInterpolator() {
        return mInterpolator;
    }

    public AnimationSlideInUnderneath setInterpolator(
            TimeInterpolator interpolator) {
        mInterpolator = interpolator;
        return this;
    }

    public long getDuration() {
        return mDuration;
    }

    public AnimationSlideInUnderneath setDuration(long duration) {
        mDuration = duration;
        return this;
    }

    public long getDelay() {
        return mDelay;
    }

    public AnimationSlideInUnderneath setDelay(int delay) {
        mDelay = delay;
        return this;
    }

    public AnimationListener getListener() {
        return mListener;
    }

    public AnimationSlideInUnderneath setListener(AnimationListener listener) {
        mListener = listener;
        return this;
    }

    public long getPadding() {
        return mPadding;
    }

    public AnimationSlideInUnderneath setPadding(int padding) {
        mPadding = padding;
        return this;
    }
}
